package tool;

import org.jfree.chart.ChartFactory;
import org.jfree.chart.ChartPanel;
import org.jfree.chart.JFreeChart;
import org.jfree.chart.axis.ValueAxis;
import org.jfree.chart.labels.StandardCategoryItemLabelGenerator;
import org.jfree.chart.labels.StandardPieSectionLabelGenerator;
import org.jfree.chart.plot.CategoryPlot;
import org.jfree.chart.plot.PiePlot;
import org.jfree.chart.plot.PlotOrientation;
import org.jfree.chart.renderer.category.BarRenderer;
import org.jfree.data.category.DefaultCategoryDataset;
import org.jfree.data.general.DefaultPieDataset;

import java.text.DecimalFormat;
import java.text.NumberFormat;
import java.util.Iterator;
import java.util.List;
import java.util.Map;

public class CategoryChartBuilder {

    private CategoryChartBuilder(){}
    private String name;
    private String categoryAxisLabel,valueAxisLabel;
    public static CategoryChartBuilder create()
    {
        return new CategoryChartBuilder();
    }

    public String getName() {
        return name;
    }

    public CategoryChartBuilder setName(String name) {
        this.name = name;
        return this;
    }
    public CategoryChartBuilder title(String title)
    {
        this.setName(title);
        return this;
    }
    private DefaultCategoryDataset categoryDataset;
    private DefaultPieDataset pieDataset;
    public CategoryChartBuilder xyLabel(String x, String y)
    {
        valueAxisLabel = y;
        categoryAxisLabel = x;
        return this;
    }
    public CategoryChartBuilder geneData(List<String> x, List<Float> y,String group)
    {
        this.categoryDataset = CreateSingleBarDataSet(x,y,group);
        return this;
    }
    public CategoryChartBuilder geneData(List<List<String>> x, List<Float> y)
    {
        this.categoryDataset = CreateSingleBarDataSet(x,y);
        return this;
    }
    public CategoryChartBuilder geneData(Map<String,Float> info)
    {
        this.pieDataset = createPieDataset(info);
        return this;
    }
    private boolean legend;
    private int barTick = 1;

    public CategoryChartBuilder setBarTick(int barTick) {
        this.barTick = barTick;
        return this;
    }

    public boolean isLegend() {
        return legend;
    }

    public CategoryChartBuilder setLegend(boolean legend) {
        this.legend = legend;
        return this;
    }

    public ChartPanel buildBar()
    {
        JFreeChart barChart = ChartFactory.createBarChart(
                getName(),
                categoryAxisLabel,
                valueAxisLabel,
                categoryDataset,
                PlotOrientation.VERTICAL,
                isLegend(),
                true, false);

        CategoryPlot plot = (CategoryPlot) barChart.getPlot();
        ValueAxis rangeAxis = plot.getRangeAxis();
        rangeAxis.setAutoTickUnitSelection(false);
        rangeAxis.setMinorTickCount(barTick);
        rangeAxis.setAutoRangeMinimumSize(barTick);

        BarRenderer barrenderer = new BarRenderer();
        barrenderer.setMaximumBarWidth(0.1);
        barrenderer.setMinimumBarLength(0.1);
        barrenderer.setBaseItemLabelGenerator(new StandardCategoryItemLabelGenerator());//显示每个柱的数值
        barrenderer.setBaseItemLabelsVisible(true);

        plot.setRenderer(barrenderer);
        plot.setRangeAxis(rangeAxis);
        return create(barChart);
    }
    public ChartPanel buildLine()
    {
        JFreeChart lineChart = ChartFactory.createLineChart(
                getName(),
                categoryAxisLabel,
                valueAxisLabel,
                categoryDataset,
                PlotOrientation.VERTICAL,
                isLegend(),
                true,false);

        return create(lineChart);
    }
    private ChartPanel create(JFreeChart jFreeChart)
    {
        return new ChartPanel(jFreeChart);
    }
    public ChartPanel buildPie()
    {
        JFreeChart chart = ChartFactory.createPieChart(
                getName(),  // chart title
                pieDataset,        // data
                isLegend(),           // include legend
                true,
                false);

        PiePlot pieplot = (PiePlot) chart.getPlot();
        DecimalFormat df = new DecimalFormat("0.00%");//获得一个DecimalFormat对象，主要是设置小数问题
        NumberFormat nf = NumberFormat.getNumberInstance();//获得一个NumberFormat对象
        StandardPieSectionLabelGenerator sp1 = new StandardPieSectionLabelGenerator("{0}  {2}", nf, df);//获得StandardPieSectionLabelGenerator对象
        pieplot.setLabelGenerator(sp1);//设置饼图显示百分比

        //没有数据的时候显示的内容
        pieplot.setNoDataMessage("无数据显示");
        pieplot.setCircular(false);
        pieplot.setLabelGap(0.02D);

        pieplot.setIgnoreNullValues(true);//设置不显示空值
        pieplot.setIgnoreZeroValues(true);//设置不显示负值
        return create(chart);
    }
    private DefaultCategoryDataset CreateSingleBarDataSet(List<String> x, List<Float> y ,String group)
    {
        final DefaultCategoryDataset dataset = new DefaultCategoryDataset();
        int xl = x.size();
        int yl = y.size();
        if (xl != yl)
        {
            throw new IndexOutOfBoundsException("x != y" + xl + "-" + yl);
        }
        Iterator<String> xi = x.iterator();
        Iterator<Float> yi = y.iterator();
        while (xi.hasNext() && yi.hasNext())
        {
            String nextx = xi.next();
            Float nexty = yi.next();
            dataset.addValue( nexty,group,nextx);
        }
        return dataset;
    }
    private DefaultCategoryDataset CreateSingleBarDataSet(List<List<String>> x, List<Float> y)
    {
        final DefaultCategoryDataset dataset = new DefaultCategoryDataset();
        int xl = x.size();
        int yl = y.size();
        if (xl != yl)
        {
            throw new IndexOutOfBoundsException("x != y" + xl + "-" + yl);
        }
        Iterator<List<String>> xi = x.iterator();
        Iterator<Float> yi = y.iterator();
        while (xi.hasNext() && yi.hasNext())
        {
            List<String> nextx = xi.next();
            Float nexty = yi.next();
            dataset.addValue( nexty,nextx.get(0),nextx.get(1));
        }


        return dataset;
    }

    private void checkSize(List<String> x, List<Float> y)
    {
        int xl = x.size();
        int yl = y.size();
        if (xl != yl)
        {
            throw new IndexOutOfBoundsException("x != y" + xl + "-" + yl);
        }
    }

    private DefaultPieDataset createPieDataset(Map<String,Float> map)
    {

        DefaultPieDataset dataset = new DefaultPieDataset( );
        for (String key:map.keySet())
        {
            dataset.setValue(key,map.get(key));
        }

        return dataset;
    }

}
